package ui;

import control.Control;
import ui.dnd.DragAndDropTransferHandler;
import ui.dnd.RowDropTargetListener;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Deshun
 * Date: 2/14/13
 * Time: 11:20 AM
 * To change this template use File | Settings | File Templates.
 */
public class FormPanel {
//TODO drag and drop for rows as well as cells.

    private static List<FormRow> formRowList;
    private static DataFlavor dragAndDropRowDataFlavor;
    private FormArea parent;
    private JPanel panel;
    JButton newRowButton;

    FormPanel(FormArea formArea) {
        formRowList = new ArrayList<FormRow>();
        setPanel(new JPanel(new GridBagLayout()));
        newRowButton = new JButton("Add Row");
        newRowButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addRow();
                explode();
                getPanel().revalidate();
            }
        });

        getPanel().setTransferHandler(new DragAndDropTransferHandler());

        getPanel().setDropTarget(new DropTarget(getPanel(), new RowDropTargetListener(this)));
        setParent(formArea);
        addRow();
    }

    public Component explode() {
        if ( getPanel().getComponentCount() > 0 ) {
            getPanel().removeAll();
        }
        getPanel().setOpaque(false);

        final GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.gridx = 0;
        constraints.anchor = GridBagConstraints.NORTHWEST;
//        constraints.weighty = 0.0;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.insets = new Insets(15, 5, 0, 5);

        int row = 0;
        //TODO think of a way to handle header ie. storing and loading as well as identifying when exploding

        for ( FormRow current : getRows() ) {
            constraints.gridy = row++;
            getPanel().add(current.explode(), constraints);
        }

        constraints.gridy = row++;
        getPanel().add(newRowButton, constraints);

        constraints.weighty = 1.0;
        constraints.weightx = 1.0;
        constraints.fill = GridBagConstraints.BOTH;
        Component strut = Box.createVerticalStrut(1);
        getPanel().add(strut, constraints);

        return getPanel();
    }

    int addControl(int rowNumber, Control control) {
        if ( rowNumber > formRowList.size() ) {
            System.out.println("row number > row size: adding failed");
            return 0;
        }
        control.setRowNumber(rowNumber);
        formRowList.get(rowNumber).addControl(control);
        return 0;
    }

    void removeControl(int rowNumber, Control control) {
        formRowList.get(rowNumber).removeControl(control);
        if ( formRowList.get(rowNumber).isEmpty() ) {
            removeRow(rowNumber);
            reassignPosition();
        }
    }

    void reassignPosition() {
        int position = 0;
        for ( FormRow currentRow : getRows() ) {
            currentRow.setRowNumber(position++);
        }
    }

    public void addRow() {
        FormRow newFormRow = new FormRow(this);
        newFormRow.setRowNumber(formRowList.size());
        formRowList.add(newFormRow);
    }

    void removeRow(int rowNumber) {
        formRowList.remove(rowNumber);
    }

    public List<FormRow> getRows(){
        return formRowList;
    }

    Component requestToolbar(FormRow formRow) {
        return getParent().requestToolbar(getRows().indexOf(formRow));
    }



    public FormArea getParent() {
        return parent;
    }

    public void setParent(FormArea parent) {
        this.parent = parent;
    }

    public static DataFlavor getDragAndDropRowDataFlavor() throws Exception {
        if (dragAndDropRowDataFlavor == null)
            dragAndDropRowDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType +";class=ui.FormRow");
        return dragAndDropRowDataFlavor;
    }

    public JPanel getPanel() {
        return panel;
    }

    public void setPanel(JPanel panel) {
        this.panel = panel;
    }
}
